require "playerdata"
local skynet = require "skynet"
local gameCmd = require "game_proto"
local tablelogic = require "tablelogic"
local chairs = require "chair"

local CMD = {}
local TableFrame = {}
local MainCmdId = gameCmd.Main_ClientAndGameSvr_TableModle

local maxPlayer = 4
local WSK_TEAMONE = 1
local WSK_TEAMTWO = 2
local MAX_WSK_OUTCOUNT = 23
local MAX_WSK_CARDCOUNT = 26

--牌型
local PKTYPE = 
{
    UNDEF  =  0,--[[未定义]]      SINGLE  =  1,--[[单张]]      DUIZI  =  2,--[[对子]]
    SHUNZI =  3,--[[顺子]]        LIANDUI =  4,--[[连对]]      SZHADAN=  5,--[[普通炸弹]]
    DZHADAN=  6,--[[翻倍炸弹]]    ZWSK    =  7,--[[杂五十K]]   TWSK   =  8,--[[同花50K]]
    DUIWANG=  9,--[[对王]]        SWANG   = 10,--[[四王]]
}
local WSKPLACE = 
{    
    PLACEUNDEF  =   -1,     --位置未定义
    PLACEONE    =    0,     --一游
    PLACETWO    =    1,     --二游
    PLACETHREE  =    2,     --三游
    PLACEFOUR   =    3,     --四游
}
local WSKGAMETYPE = 
{
    WSKTYPEUNDEF =    0,	--游戏类型未定义
	WSKMINGJIAO  =    1,	--明叫
    WSKANJIAO    =    2,	--暗叫
    WSKHOUPAI    =    3,	--吼牌
}

local WSKOPER = 
{
	UNDEF 	= 0x00,
	PRESS 	= 0x01,
	OUTCARD = 0x02,
}

function send_data(addr,msg)
    skynet.send(addr,"lua","send_data",msg)
end

function SendDataInLua(sendAddr,subId, msg)    
    local msgSend = string.pack('>I2>I2', MainCmdId, subId)
    if msg then msgSend = msgSend..msg end
    send_data(sendAddr, msgSend)
end

function CMD.SetTableData(Table, nMaxPlayerCount, ndiFen, nMa, nFangPaoOrZiMo, nDianPaoMaOrZiMoMa, nKeQiangGang, externData)
    print('nMaxPlayerCount is '..nMaxPlayerCount)
    --tablelogic.InitChair(nMaxPlayerCount)
    local makeRoomsg = "HSWsk BasicScore: " ..ndiFen
    for chair_id = 0 , nMaxPlayerCount - 1 do 
        Table.m_pChairs[chair_id].m_isValid = 1
        Table.m_pChairs[chair_id].IsReady = 1

    end

    return makeRoomsg, Table
end

function CMD.OnSitDownSucess(Player)
    print('OnSitDownSucess')

    local pos = 0
    for i=0, 3 do
        skynet.error("-----------------------------")
        skynet.error("SitDownSuccess Player=", Player)

        if TableFrame.chairObj[i] == nil then
            TableFrame:ChairObjReset(i, Player)
			pos = i
            break
        end
    end   
	
	skynet.error("TableFrame.bankUsr= ", TableFrame.bankUsr)
	skynet.error("pos= ", pos)
	if TableFrame.bankUsr == nil then
        TableFrame.bankUsr = pos
		skynet.error("TableFrame.bankUsr= ", TableFrame.bankUsr)
    end 

    --发送消息
    local msg = string.pack(">I2>I2<I4<I4", 303, 2070, 2001, 4)
	--再告诉客户端几人麻将
    send_data(Player.nAgentAddr, msg)
end

function CMD.OnGameMessage(scmd,smsg,Player)
    if scmd == gameCmd.Sub_ClientToGameSvr_TableModle_WskJiaoPai then
        
        return TableFrame:OnNetMsgJiaoPai(smsg, Player)

    elseif scmd == gameCmd.Sub_ClientToGameSvr_TableModle_WskHouPai then

        return TableFrame:OnNetMsgHouPai(smsg, Player)

    elseif scmd == gameCmd.Sub_ClientToGameSvr_TableModle_WskOutCard then

        return TableFrame:OnNetMsgPukeOutCardReq(smsg, Player)

    elseif scmd == gameCmd.Sub_ClientToGameSvr_TableModle_WskPress then 

        return TableFrame:OnNetMsgPukePress(smsg, Player)

    elseif scmd == gameCmd.Sub_ClientToGameSvr_TableModle_WskNotHou then

        return TableFrame:OnNetMsgNotHou(smsg, Player)

    end
end

function CMD.OnEventGameStart(Table, itableframe)
    skynet.error("In TableFrameSink GameStart")
    TableFrame:Reset()

    --设置庄家
    TableFrame.currentUsr = TableFrame.bankUsr
	skynet.error("GameStart currentUsr= ", TableFrame.currentUsr)
	
    --组播游戏开始
	TableFrame:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_GameStart)
	--[[
    for i=0, 3 do
        if TableFrame.chairObj[i] ~= nil then
            SendDataInLua(TableFrame.chairObj[i].player.nAgentAddr, gameCmd.Sub_GameSvrToClient_TableModle_GameStart)
        end
    end
	--]]
	
    --random cards

    --4个人发牌
    for i=0, 3 do
        if TableFrame.chairObj[i] ~= nil then
            for j=0, 26 do
				TableFrame.chairObj[i].mcbCards[j] = tablelogic.cardData[27*(i)+j+1]
				if j > 10 then 
					TableFrame.chairObj[i].mcbCards[j] = 0x0
				end
            end
            ---[[
            for k,v in pairs (TableFrame.chairObj[i].mcbCards) do
                --skynet.error(v)
            end
            --skynet.error("------------------------------------------")
            --]]
        end
    end
    --skynet.error("------------------------------------------")

	--发送信息
    for i=0, 3 do
        if TableFrame.chairObj[i] ~= nil then
            local dataBuf = ''
            --skynet.error("before:", string.len(dataBuf))
            dataBuf = dataBuf..string.pack('<I2I2I2', TableFrame.bankUsr, TableFrame.currentUsr, 0)
            for j=0, 26 do
			  --skynet.error("TableFrame.chairObj[i].mcb= ", TableFrame.chairObj[i].mcbCards[j])
                dataBuf = dataBuf..string.pack('<B', TableFrame.chairObj[i].mcbCards[j])
            end
            for j=0, 3 do
                dataBuf = dataBuf..string.pack('<I', 0)
            end
            --skynet.error("after:", string.len(dataBuf))
            --skynet.error("TableFrame.chairObj[i].nAgentAddr:", TableFrame.chairObj[i].player.nAgentAddr)
            --skynet.error("------------------------------------------")
            SendDataInLua(TableFrame.chairObj[i].player.nAgentAddr, gameCmd.Sub_GameSvrToClient_TableModle_WskStart, dataBuf)
        end
    end
end

function TableFrame.GetChairs(i)

    if i==0 then
        skynet.error("return chairAddr1=", TableFrame.chairs[0])
        return TableFrame.chairs[0]
    end
    if i==1 then
        skynet.error("return chairAddr2=", TableFrame.chairs[1])
        return TableFrame.chairs[1]  
    end
    if i==2 then
        skynet.error("return chairAddr3=", TableFrame.chairs[2])
        return TableFrame.chairs[2]  
    end
    if i==3 then
        skynet.error("return chairAddr4=", TableFrame.chairs[3])
        return TableFrame.chairs[3] 
    end
end

--TableFrame复位
function TableFrame:Init()
    self.chairObj       =   {}        						 --椅子
    self.diFen          =   1        						 --底分
    self.fengDing       =   128      						 --封顶

    self.bankUsr        =   nil       						 --庄家
    self.currentUsr     =   nil       						 --当前用户
	self.wLastOutCardUser = nil
    self.gameType       =   nil						         --游戏类型
    self.jiaoPaiData    =   nil       						 --叫牌数据
    self.thisChair      =   nil       
    self.gameScore      =   nil			       				 --游戏积分
    self.nWskScoreCount =   nil      						 --五十K牌面分数
    self.disphTeamOk    =   nil      						 --分队完成标志
    self.conclueYou     =   nil     						 --几游位置
    self.lastOutCards   =   nil       						 --最后一手牌
    self.oneJuPlace     =   {}       						 --每局位置 
	self.nBei			=   nil
	
end

function TableFrame:Reset()
    --self.bankUsr        =   nil
    self.currentUsr     =   65535
	self.wLastOutCardUser = 65535
    self.gameType       =   WSKGAMETYPE.WSKTYPEUNDEF
    self.jiaoPaiData    =   nil
    self.thisChair      =   nil
    self.gameScore      =   self.diFen
    self.nWskScoreCount =   0
    self.disphTeamOk    =   false
    self.lastOutCards   =   {}
    self.conclueYou     =   0
	self.nBei			=   1

	for i=0, maxPlayer-1 do 
		self.oneJuPlace[i] = 65535
	end
	
    for i=0, maxPlayer-1 do
        if self.chairObj[i] ~= nil then
            self.chairObj[i].isOver = false                       --是否打完标志
            self.chairObj[i].overFlag = WSKPLACE.PLACEUNDEF       --位置
            self.chairObj[i].teamFlag = nil
            self.chairObj[i].leftCardCount = 27                   --剩余手牌数量
			self.chairObj[i].lastOutCards = {}
            self.chairObj[i].mcbCards = {}                        --手牌
            self.chairObj[i].isHou = 0
            self.chairObj[i].isMingJiao = 0
            self.chairObj[i].isAnJiao = 0
			self.chairObj[i].isBang = 0
			self.chairObj[i].isQing = 0
			self.chairObj[i].zWskCount = 0
			self.chairObj[i].tWskCount = 0
			self.chairObj[i].dZhaDanCount = 0
			self.chairObj[i].shWangCount = 0
			self.chairObj[i].siWangCount = 0
			self.chairObj[i].wskScore = 0
			self.chairObj[i].gameScore = 0
			self.chairObj[i].outCardStatus = WSKOPER.UNDEF
        end
    end
end

function TableFrame:ChairObjReset(chairID, player)

    self.chairObj[chairID] = {}
    self.chairObj[chairID].player = player                      --玩家
    self.chairObj[chairID].chairID = chairID                    --椅子ID

    self.chairObj[chairID].isOver = false                       --打完标志
    self.chairObj[chairID].overFlag = WSKPLACE.PLACEUNDEF       --位置
    self.chairObj[chairID].teamFlag = nil
	self.chairObj[chairID].leftCardCount = 27                   --剩余手牌数量·
    self.chairObj[chairID].lastOutCards = {}
	self.chairObj[chairID].mcbCards = {}                        --手牌
    self.chairObj[chairID].isHou = 0
    self.chairObj[chairID].isMingJiao = 0
    self.chairObj[chairID].isAnJiao = 0
	self.chairObj[chairID].isBang = 0
	self.chairObj[chairID].isQing = 0
	self.chairObj[chairID].zWskCount = 0
	self.chairObj[chairID].tWskCount = 0
	self.chairObj[chairID].dZhaDanCount = 0
	self.chairObj[chairID].shWangCount = 0
	self.chairObj[chairID].siWangCount = 0
	self.chairObj[chairID].wskScore = 0
	self.chairObj[chairID].gameScore = 0
	self.chairObj[chairID].nTotalJuGameScore = 0
	self.chairObj[chairID].outCardStatus = WSKOPER.UNDEF
	
    skynet.error("TableFrame.chairObj[chairID]= ", self.chairObj[chairID])
    skynet.error("player = ", player)
    skynet.error("TableFrame.chairObj[chairID].player= ", self.chairObj[chairID].player)
    skynet.error("TableFrame.chairObj[i].player.nAgentAddr= ", self.chairObj[chairID].player.nAgentAddr)    
    skynet.error("-----------------------------")
end

function TableFrame:BroadCastData(subId, msg)    
    local msgSend = string.pack('>I2>I2', MainCmdId, subId)
    if msg then msgSend = msgSend..msg end
    --skynet.error("playerAddr= ", self.player.nAgentAddr)
    for i,v in pairs (self.chairObj) do
        send_data(v.player.nAgentAddr, msgSend)
    end
end

function TableFrame:GetChair(player)
    for k,v in pairs(TableFrame.chairObj) do
        if player.nAgentAddr == v.player.nAgentAddr then
			skynet.error("chairObj[xxx]= ", v)
            return v
        end
    end

    return nil
end

function TableFrame:CheckJiaoType(chair, cardData)
    local num = 0

    for k, v in pairs (chair.mcbCards) do
        if cardData == v then
            num = num + 1
        end
    end

    if num == 1 then
        return WSKGAMETYPE.WSKMINGJIAO
    else
        return WSKGAMETYPE.WSKANJIAO
    end
end

function TableFrame:OnNetMsgJiaoPai(smsg, Player)
    skynet.error("TableFrame.gameType= ", TableFrame.gameType)
    if TableFrame.gameType ~= WSKGAMETYPE.WSKTYPEUNDEF then
        return
    end

    local jiaoPaiData = string.unpack("B", smsg,  5) 
    self.jiaoPaiData = jiaoPaiData

    skynet.error("jiaoPaiData= ", jiaoPaiData)
    skynet.error("player= ", Player)
	skynet.error("before self.thisChair= ", self.thisChair)
    self.thisChair = self:GetChair(Player)
	skynet.error("after self.thisChair= ", self.thisChair)

    --Logic
    ---[[
    self.gameType = self:CheckJiaoType(self.thisChair, jiaoPaiData)
    if self.gameType==WSKGAMETYPE.WSKMINGJIAO then
        self.thisChair.isMingJiao = 1
        self.gameScore = self.diFen
        self.thisChair.teamFlag = WSK_TEAMONE

    elseif self.gameType==WSKGAMETYPE.WSKANJIAO then
        self.thisChair.isAnJiao = 1
        self.gameScore = self.diFen*3
    end
    --]]

    skynet.error("self.gameType= ", self.gameType)
    skynet.error("chair.chairID= ", self.thisChair.chairID)
    skynet.error("jiaoPaiData= ", jiaoPaiData)

    local dataBuf = ''
    skynet.error("before:", string.len(dataBuf))
    dataBuf = dataBuf..string.pack('<I4I2B', self.gameType, self.thisChair.chairID, jiaoPaiData)
    skynet.error("after:", string.len(dataBuf))

    self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_Game_WskJiaoHouPai, dataBuf)
end

function TableFrame:OnNetMsgHouPai(smsg, Player)
    skynet.error("OnNetMsgHouPai TableFrame.gameType= ", TableFrame.gameType)
    if TableFrame.gameType ~= WSKGAMETYPE.WSKTYPEUNDEF then
        return
    end
    local chair = self:GetChair(Player)

    --Logic
    ---[[ 
    self.gameType = WSKGAMETYPE.WSKHOUPAI	
    self.gameScore = self.diFen*4
    if self.gameScore > self.fengDing then
        self.gameScore = self.fengDing
    end
	self.nBei = self.nBei*4
    chair.isHou = 1
	self.currentUsr = chair.chairID
    --]]

    local dataBuf = ''
    skynet.error("before:", string.len(dataBuf))
    dataBuf = dataBuf..string.pack('<I4I2B', self.gameType, chair.chairID, 0)
    skynet.error("after:", string.len(dataBuf))

    self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_Game_WskJiaoHouPai, dataBuf)
end

function TableFrame:OnNetMsgNotHou(smsg, Player)
    local chair = self:GetChair(Player)
    local dataBuf = ''
	skynet.error("before:", string.len(dataBuf))
	skynet.error("chair.chairID= ", chair.chairID)
    dataBuf = dataBuf..string.pack('<I2', chair.chairID)
	skynet.error("before:", string.len(dataBuf))

    self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_Game_WskJiaoHouPai, dataBuf)
end

function TableFrame:OnNetMsgPukeOutCardReq(smsg, Player)
    local chair = self:GetChair(Player)
    self.thisChair = chair
    
	--出牌解包与赋值
    local outCardData = {}
    local s = string.unpack("c27", smsg,  5)
    for i=0, 26 do
        --print("%d", string.byte(outCardData, i)) 
    end
    for i=0, 23 do
        outCardData[i] = string.byte(s, i+1)
    end
    self.lastOutCards = outCardData
    
    --检测出牌数据正确情况，若出的牌确实手里有则将牌删除
    self:CheckOutCardError(outCardData, chair)

    --检测分队
    self:CheckTeam(outCardData, chair)
	
    --算分
    self:CalcWskScore()
    self:CalcGameScore()
	
    --出牌赋值
    self.wLastOutCardUsr = self.thisChair.chairID
	for i=0, MAX_WSK_OUTCOUNT do
		self.lastOutCards[i] = outCardData[i]
	end		
	
    --检测是否结束
    if self:CheckIsConclue()==true then 
        return
    end

    --预打完玩家检测，若有则置为打完
    for i=0, 3 do 
		--skynet.error("self.currentUsr= ", self.currentUsr)
        if i~=self.currentUsr and self.chairObj[i]~=nil then
            if self.chairObj[i].isOver==false and self.chairObj[i].overFlag~=WSKPLACE.PLACEUNDEF then
                self.chairObj[i].isOver = true
            end
        end
    end

    --若还没结束，那么计算下一位用户位置，并发送给客户端
    self:CalcNextUsr()
	
    --发送信息给客户端
    local dataBuf = ''
    dataBuf = dataBuf..string.pack('<I2I2I2I2', chair.chairID, self.currentUsr, self.oneJuPlace[0], self.oneJuPlace[1])
    for i=0, 23 do
        dataBuf = dataBuf..string.pack('<B', outCardData[i])
    end
    dataBuf = dataBuf..string.pack('<I4', self:GetCbCardCount(self.thisChair))
   
    skynet.error("Now BroadCastData!")
    self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskOutCard, dataBuf)
end

function TableFrame:GetCbCardCount(chair)
	local count = 0
	for i=0, 27 do
		if chair.mcbCards[i] ~= 0 then 
			count = count + 1
		end
	end
	
	return count
end

function TableFrame:CheckIsConclue()
    --检测自己手里牌，还有牌就return
    local iRet = self:CheckHaveCards(self.thisChair)
    if iRet == false then
        return false
    end
    
	--若是刚好把牌打出后手里没牌了，就给个排名位置 
    for i=0, 3 do
        if self.oneJuPlace[i] == nil then
            self.oneJuPlace[i] = self.thisChair.chairID
            self.thisChair.overFlag = i
            break
        end
    end
    --若i==2了，那么此时就已经分出胜负，结算
    if i==2 then
        self.conclueYou = 0x03
        self:CheckThreePlace()
        self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount + self.nWskScoreCount
        self:ConcluedGame()
        return true
    end

    --若是暗叫或者吼牌，则此时就可以结束本局游戏了
    if self.gameType==WSKGAMETYPE.WSKHOUPAI or self.gameType==WSKGAMETYPE.WSKANJIAO then
        self.conclueYou = 0x01
        self:CheckOnePlace()
        self.thisChair.wskScore = self.thisChair.wskScore + self.nWskScoreCount
        self:ConcluedGame()
        return true
    end

    --当明叫情况下，就需要判断队友了
    if self:CheckTwoPlace()==true then
        self.conclueYou = 0x02
        self.chairObj[self.oneJuPlace[1].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[1].chairID].nWskScoreCount + self.nWskScoreCount
        self:ConcluedGame()
        return true
    end

    return false
end

function TableFrame:ConcluedGame()
	local placeArray = {}
	for i=0, maxPlayer-1 do 
		placeArray[i] = 65535
	end

	--明叫队友加上标识
	if self.gameType == WSKGAMETYPE.WSKMINGJIAO then
		local mingJiaoChair = 0
		for i=0, maxPlayer-1 do
			if self.chairObj[i].isMingJiao == true then
				mingJiaoChair = i
				break
			end
		end
		
		--找队友
		for i=0, maxPlayer-1 do
			if self.chairObj[i].teamFlag == self.chairObj[mingJiaoChair].teamFlag then
				self.chairObj[i].isMingJiao = true
			end
		end
	end
	
	--先定 placeArray0~3 排名顺序。 WSK_PLACEONE是一游，一定能定下来。 2,3,4游不一定能定下来。后续分支确定
	--有以下情况： 1.明叫情况为 1,2游是一队，3,4游不确定或者 1,2,3,4游一定确定   2.暗叫和吼牌模式只有 1游，2,3,4游不确定 
	for i=0, maxPlayer-1 do
		if self.chairObj[i].overFlag == WSKPLACE.WSK_PLACEONE then
			placeArray[0] = i
		elseif self.chairObj[i].overFlag==WSKPLACE.PLACETWO or self.chairObj[i].isHou==1 or self.chairObj[i].isAnJiao==1 then
			placeArray[1] = i
		elseif self.chairObj[i].overFlag == WSKPLACE.PLACETHREE then
			placeArray[2] = i
		elseif self.chairObj[i].overFlag == WSKPLACE.PLACEFOUR then
			placeArray[3] = i
		end
	end		
		
	--2游都没确定，那肯定是吼或者暗叫，而且是吼和暗叫的玩家拿的1游.那么后面3家顺序随意
	if placeArray[1] == 65535 then
		for i=1, maxPlayer-1 do
			placeArray[i] = (placeArray[0]+i)%maxPlayer
		end
	end
	
	--当2游确定但3游不确定时，明叫情况只有1种可能，同一队拿1,2游。 3,4游顺序随意
    --暗叫或吼情况，2游发的是暗叫或吼的那个人，3,4游顺序随意
	if placeArray[1]~=65535 and placeArray[2]==65535 then
		local i=0
		for k=0, maxPlayer-1 do
			if k~=placeArray[0] and k~=placeArray[1] then
				placeArray[2] = k
				i = k
				break
			end
		end
		for m=0, maxPlayer-1 do
			if m~=placeArray[0] and m~=placeArray[1] and m~=i then
				placeArray[3] = m
				break
			end
		end
	end
	
	--按游得顺序发送， 若定了1~4游，则先发1游，再2游，再3游、 否则就只发1游和吼暗叫的人 
    --发送信息给客户端
    local dataBuf = ''
	dataBuf = dataBuf..string.pack('<BI2', self.conclueYou, self.wLastOutCardUsr)
	for i=0, MAX_WSK_OUTCOUNT do
		dataBuf = dataBuf..string.pack('<B', self.lastOutCards[i])
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I1', self.chairObj[i].isMingJiao)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I1', self.chairObj[i].isAnJiao)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I1', self.chairObj[i].isHou)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I1', self.chairObj[i].isBang)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I1', self.chairObj[i].isQing)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].zWskCount)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].tWskCount)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].dZhaDanCount)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].shWangCount)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].siWangCount)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].player.nPlayerId)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].wskScore)
	end
	for i=0, maxPlayer-1 do
		dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].gameScore)
	end
	
	self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskConclued, dataBuf)
	
	for i=0, maxPlayer-1 do
		self.chairObj[i].nTotalJuGameScore = self.chairObj[i].nTotalJuGameScore + self.chairObj[i].gameScore
	end

	self.bankUsr = placeArray[0]
	
	skynet.call("itableframe", "lua", "ConcludeGameFriend", self)
end

--[[
skynet.error("-------------------------------")
		skynet.error("isMingJiao= ", self.chairObj[i].isMingJiao)
		skynet.error("isAnJiao= ", self.chairObj[i].isAnJiao)
		skynet.error("isHou= ", self.chairObj[i].isHou)
		skynet.error("isBang= ", self.chairObj[i].isBang)
		skynet.error("isQing= ", self.chairObj[i].isQing)
		skynet.error("zWskCount= ", self.chairObj[i].zWskCount)
		skynet.error("tWskCount= ", self.chairObj[i].tWskCount)
		skynet.error("tWskCount= ", self.chairObj[i].tWskCount)
		skynet.error("tWskCount= ", self.chairObj[i].tWskCount)
		skynet.error("dZhaDanCount= ", self.chairObj[i].dZhaDanCount)
		skynet.error("shWangCount= ", self.chairObj[i].shWangCount)
		skynet.error("siWangCount= ", self.chairObj[i].siWangCount)
		skynet.error("wskScore= ", self.chairObj[i].wskScore)
		skynet.error("gameScore= ", self.chairObj[i].gameScore)
--]]

function TableFrame:CheckHaveCards(chair)
    for i=0, MAX_WSK_CARDCOUNT do
	--skynet.error("A= ", chair.mcbCards[i])
        if chair.mcbCards[i] ~= 0x0 then
            return false
        end
    end

    return true
end

function TableFrame:CheckThreePlace()
    for i=0, 3 do 
        if i~=self.oneJuPlace[0] and i~=self.oneJuPlace[1] and i~=self.oneJuPlace[2] then
            self.thisChair.isOver = WSKPLACE.PLACEFOUR
            self.oneJuPlace[3] = i
        end
    end

    local getScore = self.chairObj[self.oneJuPlace[3].chairID].nWskScoreCount
    self.chairObj[self.oneJuPlace[3].chairID] = self.chairObj[self.oneJuPlace[3].chairID] - getScore
    self.chairObj[self.oneJuPlace[0].chairID] = self.chairObj[self.oneJuPlace[0].chairID] + getScore

    local  hanScore = self:GetHandScore(self.chairObj[self.oneJuPlace[3]])
    if self.chairObj[self.oneJuPlace[3].chairID].teamFlag == self.chairObj[self.oneJuPlace[0].chairID].teamFlag then
        self.chairObj[self.oneJuPlace[1].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[3].chairID].nWskScoreCount + handScore
    else
        self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[0].chairID] + hanScore
    end

    local teamWin = -1
    --是否有清，有清*4
    if self.chairObj[self.oneJuPlace[0].chairID].teamFlag == self.chairObj[self.oneJuPlace[0].chairID].teamFlag then
        teamWin = 0
        if self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount==200 then
            self.chairObj[self.oneJuPlace[0].chairID].isQing = 1
            self.chairObj[self.oneJuPlace[2].chairID].isQing = 1
        elseif self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount==0 then
            self.chairObj[self.oneJuPlace[1].chairID].isQing = 1
            self.chairObj[self.oneJuPlace[3].chairID].isQing = 1
        end
    else
        teamWin = 1
        if self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[3].chairID].nWskScoreCount==200 then
            self.chairObj[self.oneJuPlace[0].chairID].isQing = 1
            self.chairObj[self.oneJuPlace[3].chairID].isQing = 1
        elseif self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount==0 then
            self.chairObj[self.oneJuPlace[1].chairID].isQing = 1
            self.chairObj[self.oneJuPlace[2].chairID].isQing = 1
        end
    end

    local countQing = 0
    for i=0, 3 do
        if self.chairObj[i].isQing==1 then
            countQing = countQing + 1
        end
    end

    if countQing == 2 then
        self.gameScore = self.gameScore*4
        if self.gameScore > self.fengDing then
            self.gameScore = self.fengDing 
        end
    end

    --再判断是哪个队赢
    if teamWin == 0 then
        if self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[2].chairID].nWskScoreCount > 100 then
            for i=0, 3 do 
                if self.oneJuPlace[0]==i or self.oneJuPlace[2]==i then
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount + self.gameScore
                else
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount - self.gameScore
                end
            end
        else 
            for i=0, 3 do 
                if self.oneJuPlace[0]==i or self.oneJuPlace[2]==i then
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount - self.gameScore
                else
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount + self.gameScore
                end
            end 
        end
    elseif teamWin == 1 then
         if self.chairObj[self.oneJuPlace[0].chairID].nWskScoreCount+self.chairObj[self.oneJuPlace[3].chairID].nWskScoreCount > 100 then
            for i=0, 3 do 
                if self.oneJuPlace[0]==i or self.oneJuPlace[3]==i then
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount + self.gameScore
                else
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount - self.gameScore
                end
            end
        else 
            for i=0, 3 do 
                if self.oneJuPlace[0]==i or self.oneJuPlace[3]==i then
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount - self.gameScore
                else
                    self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount = self.chairObj[self.oneJuPlace[i].chairID].nWskScoreCount + self.gameScore
                end
            end 
        end
    end
end

function TableFrame:CheckOnePlace()
    local  houOrAnjiaoChair = -1

    for  i=0, 3 do
        if self.chairObj[i].isAnJiao==1 or self.chairObj[i].isHou==1 then    
            houOrAnjiaoChair = i
            break
        end
    end

    --若拿一游的是吼或者暗叫的玩家则该玩家加分
    if self.thisChair.chairID == houOrAnjiaoChair then 
        for i=0, 3 do 
            if i==self.thisChair.chairID then
                self.chairObj[i].ganmeScore = self.chairObj[i].gameScore + self.gameScore
            else
                self.chairObj[i].ganmeScore = self.chairObj[i].gameScore - self.gameScore
            end

        end
    else
        --不是，则吼/暗叫者减3人份的分
        for i=0, 3 do 
            if i==self.thisChair.chairID then
                self.chairObj[i].ganmeScore = self.chairObj[i].gameScore - self.gameScorex
            else
                self.chairObj[i].ganmeScore = self.chairObj[i].gameScore + self.gameScore
            end
        end
    end
end

function TableFrame:CheckTwoPlace()
    local iRet = self:CheckOneTeamOver()

    if iRet==false then 
        return false
    end

    for i=0, 3 do
        if i==self.oneJuPlace[0] or i==self.oneJuPlace[1] then
            self.chairObj[i].ganmeScore = self.chairObj[i].gameScore + self.gameScore
        else
            self.chairObj[i].ganmeScore = self.chairObj[i].gameScore - self.gameScore
        end
    end

    return true
end

function TableFrame:CheckOneTeamOver()
    if self.oneJuPlace[0]==nil or self.oneJuPlace[1]==nil then 
        return false
    end

    local  place1 = self.chairObj[self.oneJuPlace[0]].teamFlag
    local  place2 = self.chairObj[self.oneJuPlace[1]].teamFlag

    if place1==place2 then 
        self.chairObj[self.oneJuPlace[0]].isBang = true
        self.chairObj[self.oneJuPlace[1]].isBang = true
        self.gameScore = self.gameScore * 2
        if self.gameScore > self.fengDing then 
            self.gameScore = self.fengDing 
        end
       
        return true
    end

    return false
end

function TableFrame:GetHandScore(chair)
    local handScore = 0
    local temp = 0

    for i=0, MAX_WSK_CARDCOUNT do 
        if chair.mcbCards[i] ~= 0x0 then
            temp = chair.mcbCards[i]
            temp = temp << 4
            if temp == 0x30 then
                handScore = handScore + 5
            elseif temp==0x80 or temp==0xB0 then
                handScore = handScore + 10
            end
        end
    end

    return handScore
end

function TableFrame:CalcWskScore()
    local score = 0
    local temp = 0

    for i=0, MAX_WSK_OUTCOUNT do
        if self.lastOutCards[i] == 0 then
            break
        end

        temp = self.lastOutCards[i]
        temp = temp << 4
        if temp == 0x30 then
            score = score + 5
        elseif temp==0x80 or temp==0xB0 then
            score = scor + 10       
        end
    end

    self.nWskScoreCount = self.nWskScoreCount +  score

    if score ~= 0 then
        --发送数据
        local dataBuf = ''
        dataBuf = dataBuf..string.pack('<I4', self.nWskScoreCount)
        self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskCardScoreUpdate, dataBuf)
    end
end

function  TableFrame:CalcGameScore()
    local nBei = 1
    local type = self:CheckType()

    if type == PKTYPE.ZWSK then 
        self.gameScore = self.gameScore*2
        nBei = 2
        if self.thisChair.zWskCount == nil then
            self.thisChair.zWskCount = 1
        else
            self.thisChair.zWskCount = self.thisChair.zWskCount + 1
        end

    elseif type == PKTYPE.DUIWANG then
        self.gameScore = self.gameScore*2
        nBei = 2
        if self.thisChair.duiWang == nil then
            self.thisChair.duiWang = 1
        else
            self.thisChair.duiWang = self.thisChair.duiWang + 1
        end
        
    elseif type == PKTYPE.DZHADAN then
        self.gameScore = self.gameScore*2
        nBei = 2
        if self.thisChair.dZhaDan == nil then
            self.thisChair.dZhaDan = 1
        else
            self.thisChair.dZhaDan = self.thisChair.dZhaDan + 1
        end

    elseif type == PKTYPE.TWSK then
        self.gameScore = self.gameScore*4
        nBei = 2
        if self.thisChair.tWsk == nil then
            self.thisChair.tWsk = 1
        else
            self.thisChair.tWsk = self.thisChair.tWsk + 1
        end

    elseif type == PKTYPE.SWANG then
        self.gameScore = self.gameScore*4
        nBei = 2
        if self.thisChair.sWang == nil then
            self.thisChair.sWang = 1
        else
            self.thisChair.sWang = self.thisChair.sWang + 1
        end
    end

    self.nBei = nBei
    if self.gameScore > self.fengDing then
        self.gameScore = self.fengDing
    end

    if nBei ~= 1 then
         --发送数据
        local dataBuf = ''
        dataBuf = dataBuf..string.pack('<I4', self.nBei)
        self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskBeiUpdate, dataBuf)
    end

end

function TableFrame:CheckType()
    local count = 0
    local type = 0
    for i=0, MAX_WSK_OUTCOUNT do
        if self.lastOutCards[i] ~= 0x0 then
            count = count + 1
        end
    end

    if count > 13 then
        count = 13
    end

    if count == 1 then
        type = 1
    elseif count == 2 then 
        type = self:CheckTwoCards()
    elseif count == 3 then
        type = self:CheckThreeCards()
    elseif count == 4 then
        type = self:CheckFourCards()
    elseif count == 5 then
        type = self:CheckFiveCards()
    elseif count == 6 then
        type = self:CheckSixCards()
    elseif count == 7 then
        type = self:CheckSevenCards()
    elseif count == 8 then
        type = self:CheckEightCards()
    elseif count == 9 then
        type = self:CheckNineCards()
    elseif count == 10 then
        type = self:CheckTenCards()
    elseif count == 11 then
        type = self:CheckElevenCards()
    elseif count == 12 then
        type = self:CheckTwelveCards()
    elseif count == 14 then
        type = 14
    end

    return type
end

function TableFrame:OnNetMsgPukePress(smsg, Player)

	local chair = self:GetChair(Player)
	chair.lastOutCards = {}
	chair.outCardStatus = WSKOPER.PRESS
	
	self:CalcNextUsr()
	
	--检测本回合是否需要结束
	--若本轮上一个出牌者刚好就是自己，那么说明，上一轮要结束了，要算分了，并开始下一轮新的循环
	if self.currentUsr==self.wLastOutCardUser and self:CheckOtherPlayerPress(self.currentUsr) then 
		self.chairObj[self.currentUsr].wskScore = self.chairObj[self.currentUsr].wskScore + self.nWskScoreCount
		self:EveryRoundReset()
		
		local dataBuf = ''
		for i=0, maxPlayer-1 do
			dataBuf = dataBuf..string.pack('<I4', self.chairObj[i].wskScore)
		end
		self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskScoreUpdate, dataBuf)
	end
	
	local dataBuf = ''
	dataBuf = dataBuf..string.pack('<I2I2', self.currentUsr, chair.chairID)
	if self:CheckJieFeng()== true then
		dataBuf = dataBuf..string.pack('<I4', 1)
	else
		dataBuf = dataBuf..string.pack('<I4', 0)
	end
	self:BroadCastData(gameCmd.Sub_GameSvrToClient_TableModle_WskPress, dataBuf)	
end

function TableFrame:CheckJieFeng()
	--是否是预备成为已打完状态，如果是那么其实nextUsr应该是他下家或者接风的队友
	if self.chairObj[self.currentUsr].isOver == false then 
		if self.chairObj[self.currentUsr].overFlag ~= WSKPLACE.PLACEUNDEF then 
			self.chairObj[self.currentUsr].isOver = true
			self:CalcNextJieFengUsr()
			return true
		end	
	end
	
	return false
end 

function TableFrame:CalcNextJieFengUsr()
	--分队情况未知时，noTeam为true,接风为下家接
	local noTeam = false
	if self.chairObj[self.currentUsr].teamFlag == WSK_TEAMUNDEF then 
		noTeam = true
	end
	
	local i = -1
	for j=0, maxPlayer-1 do 
		if j ~= self.currentUsr then 
			if self.chairObj[j].overFlag == self.chairObj[currentUsr].overFlag then 
				i = j
				break
			end 
		end 
	end

	--有队友则队友接风
	if i~=-1 and noTeam==false then 
		self.currentUsr = i 
	else 
	--没有队友则下家接
		if self.chairObj[currentUsr+1].overFlag ~= WSKPLACE.PLACEUNDEF then 
			self.currentUsr = (self.currentUsr+2)%HSPK_GAME_PLAYER
		else 
			self.currentUsr = (self.currentUsr+1)%HSPK_GAME_PLAYER
		end
	end
end

function TableFrame:EveryRoundReset()
	self.lastOutCards = {}
	self.wLastOutCardUser = 65535
	self.nWskScoreCount = 0
	
	for i=0, maxPlayer-1 do 
		self.chairObj[i].outCardStatus = WSKOPER.UNDEF
	end
end

function TableFrame:CheckOtherPlayerPress(chairID)
	for i=0, maxPlayer-1 do 
		if self.chairObj[i].overFlag == WSKPLACE.PLACEUNDEF then
			if chairID ~= i then 
				if self.chairObj[i].outCardStatus ~= WSKOPER.PRESS then 
					return false
				end
			end
		end
	end
	
	return true
end

function TableFrame:CheckOutCardError(outCardData, chair)
    local outCardDataCout = 0
    local findCard = 0

    for i=0, 23 do
        if outCardData[i] == 0 then
            break
        end
		chair.lastOutCards[i] = outCardData[i]
        outCardDataCout = outCardDataCout+1
	end
       
	for i=0, outCardDataCout-1 do
		for j=0, MAX_WSK_CARDCOUNT do
			if outCardData[i] == chair.mcbCards[j] then
				chair.mcbCards[j] = 0x0
				findCard = findCard + 1
				break
			end
		end
	end

    skynet.error("findCard & outCardDataCout= ", findCard, outCardDataCout)
    if findCard == outCardDataCout then
        return true
    else
        return false
    end

end

function TableFrame:CheckTeam(outCardData, chair)
    if chair.isMingJiao == true then
        return
    end

    if self.gameType==WSKGAMETYPE.WSKMINGJIAO and self.disphTeamOk==false then

       if self:CheckCardsInOutCards(outCardData)==1 then
           
            chair.teamFlag = WSK_TEAMONE
            self.disphTeamOk = true
            for i=0, 3 do
                if self.chairObj[i].teamFlag == nil then
                    self.chairObj[i].teamFlag = WSK_TEAMTWO
                end
            end
        end
    end

end

function TableFrame:CheckCardsInOutCards(pData)
    for i=0, 23 do
        if self.jiaoPaiData == pData[i] then 
            return true
        end
    end

    return false
end

function TableFrame:CalcNextUsr(chair)
    
    local step = 1
	--skynet.error("(self.currentUsr+1)%maxPlayer= ", (self.currentUsr+1)%maxPlayer)
	--skynet.error("(self.currentUsr+2)%maxPlayer= ", (self.currentUsr+2)%maxPlayer)
    if self.chairObj[(self.currentUsr+1)%maxPlayer].overFlag~=WSKPLACE.PLACEUNDEF and self.chairObj[(self.currentUsr+1)%maxPlayer].isOver==true then
        step = step + 1
        if  self.chairObj[(self.currentUsr+2)%maxPlayer].overFlag~=WSKPLACE.PLACEUNDEF and self.chairObj[(self.currentUsr+1)%maxPlayer].isOver==true then 
            step = step + 1
        end
    end

    self.currentUsr = (self.currentUsr+step)%maxPlayer
end

function TableFrame:CheckTwoCards( )
    local type = 0

    local temp = self.lastOutCards[0]
    temp = temp & 0xF0

    if temp==0x50 or temp==0x52 then
        type = PKTYPE.DUIWANG
    else
        type = PKTYPE.DUIZI
    end

    return type
end

function TableFrame:CheckThreeCards( )
    local type = 0

    local temp = self.lastOutCards[0]
    temp = temp & 0xF0
    if temp==0x50 or temp==0x52 then
        type = PKTYPE.DUIWANG
    end

    temp = self.lastOutCards[0]
    temp = temp<<4
    local  temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp==temp2 then
        type = PKTYPE.SZHADAN
        return type
    end

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp==0x30 and temp2==0x80 then
        type = PKTYPE.ZWSK
        temp = self.lastOutCards[0]
        temp = tmep >> 4
        temp2 = self.lastOutCards[1]
        temp2 = temp2>>4
        local temp3 = self.lastOutCards[2]
        temp3 = temp3>>4
        if temp==temp2 and temp2==temp3 then
            type = PKTYPE.TWSK
            return type
        end
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end

function TableFrame:CheckFourCards( )
    local type = 0
    local temp = 0
    local temp2 = 0

    if self.lastOutCards[0]==0x5E or self.lastOutCards[0]==0x5F then
        type = PKTYPE.SWANG
        return type
    end

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp==temp2 then
        type = PKTYPE.SZHADAN
        return type
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end

function TableFrame:CheckFiveCards( )
    local type = 0
    local temp = 0
    local temp2 = 0

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp==temp2 then
        type = PKTYPE.SZHADAN
        return type
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end

function TableFrame:CheckSixCards( )
    local type = 0
    local temp = 0
    local temp2 = 0

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[2]
    temp2 = temp2<<4
    if temp == temp2 then 
        type = PKTYPE.DZHADAN
        return type
    end

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp == temp2 then 
        type = PKTYPE.LIANDUI
        return type
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end

function TableFrame:CheckSevenCards( )
    local type = 0
    local temp = 0
    local temp2 = 0

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[2]
    temp2 = temp2<<4
    if temp == temp2 then 
        type = PKTYPE.DZHADAN
        return type
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end

function TableFrame:CheckEightCards( )
    local type = 0
    local temp = 0
    local temp2 = 0

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[2]
    temp2 = temp2<<4
    if temp == temp2 then 
        type = PKTYPE.DZHADAN
        return type
    end

    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp == temp2 then 
        type = PKTYPE.LIANDUI
        return type
    end


    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type
end
function TableFrame:CheckNineCards( )
    --九张只可能是：  1.顺子
    return PKTYPE_SHUNZI;
end
function TableFrame:CheckTenCards( )
    --七张只可能是： 1.5连对  2.顺子
    local type = 0
    local temp = 0
    local temp2 = 0

    --5连对
    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp == tmep2 then
        type = PKTYPE.LIANDUI
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type;
end

function TableFrame:CheckElevenCards( )
    return PKTYPE.SHUNZI
end

function TableFrame:CheckTwelveCards( )
    --12张只可能是： 1.6连对 2顺子
    local type = 0
    local temp = 0
    local temp2 = 0

    -- 6连对
    temp = self.lastOutCards[0]
    temp = temp<<4
    temp2 = self.lastOutCards[1]
    temp2 = temp2<<4
    if temp == tmep2 then
        type = PKTYPE.LIANDUI
    end

    if type == 0 then
        type = PKTYPE.SHUNZI
    end

    return type;
end

skynet.start(function()
    skynet.error("tableframe server start...")
    skynet.error("command= ", command)
    skynet.dispatch("lua", function(_,_, command, ...)
        local f = CMD[command]
        skynet.ret(skynet.pack(f(...)))
    end)

    TableFrame:Init()
end)

return TableFrame